home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / macos / uae069b2.src.cpt.hqx / UAE069ß2.SRC.CPT / uae069fl2.src / audio.c next >
C/C++ Source or Header  |  1997-06-13  |  7KB  |  307 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * OS specific functions
  5.   * 
  6.   * Copyright 1995, 1996, 1997 Bernd Schmidt
  7.   * Copyright 1996 Marcus Sundberg
  8.   * Copyright 1996 Manfred Thole
  9.   */
  10.  
  11. #include "sysconfig.h"
  12. #include "sysdeps.h"
  13.  
  14. #include "config.h"
  15. #include "options.h"
  16. #include "my_memory.h"
  17. #include "custom.h"
  18. #include "gensound.h"
  19. #include "sounddep/sound.h"
  20. #include "events.h"
  21. #include "audio.h"
  22.  
  23. int sound_available = 0;
  24.  
  25. struct audio_channel_data audio_channel[4];
  26.  
  27. int sound_table[256][64];
  28. unsigned long int sample_evtime;
  29.  
  30. void init_sound_table16(void)
  31. {
  32.     int i,j;
  33.     
  34.     for (i = 0; i < 256; i++)
  35.     for (j = 0; j < 64; j++)
  36.         sound_table[i][j] = j * (uae_s8)i;
  37. }
  38.  
  39. void init_sound_table8 (void)
  40. {
  41.     int i,j;
  42.     
  43.     for (i = 0; i < 256; i++)
  44.     for (j = 0; j < 64; j++)
  45.         sound_table[i][j] = (j * (uae_s8)i) / 256;
  46. }
  47.  
  48. void AUDxDAT(int nr, uae_u16 v) 
  49. {
  50. #ifndef DONT_WANT_SOUND
  51.     struct audio_channel_data *cdp = audio_channel + nr;
  52.     cdp->dat = v;
  53.     if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
  54.     cdp->state = 2;
  55.     INTREQ(0x8000 | (0x80 << nr));
  56.     /* data_written = 2 ???? */
  57.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  58.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  59.     eventtab[ev_aud0 + nr].active = 1;
  60.     events_schedule();
  61.     }
  62. #endif
  63. }
  64.  
  65. /* Templates! I want templates! */
  66. void sample16_handler(void)
  67. {
  68. #ifndef DONT_WANT_SOUND
  69.     int nr, adk;
  70.     uae_u32 data = SOUND16_BASE_VAL;
  71.  
  72.     eventtab[ev_sample].evtime = cycles + sample_evtime;
  73.     eventtab[ev_sample].oldcycles = cycles;
  74.  
  75.     adk = adkcon;
  76.  
  77.     if (!(adk & 0x11))
  78.     data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
  79.     if (!(adk & 0x22))
  80.     data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
  81.     if (!(adk & 0x44))
  82.     data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
  83.     if (!(adk & 0x88))
  84.     data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
  85.  
  86.     PUT_SOUND_WORD (data);
  87.     check_sound_buffers ();
  88. #endif
  89. }
  90.  
  91. void sample8_handler(void)
  92. {
  93. #ifndef DONT_WANT_SOUND
  94.     int nr, adk;
  95.     uae_u32 data = SOUND8_BASE_VAL;
  96.     
  97.     eventtab[ev_sample].evtime = cycles + sample_evtime;
  98.     eventtab[ev_sample].oldcycles = cycles;
  99.     
  100.     adk = adkcon;
  101.     
  102.     if (!(adk & 0x11))
  103.     data += sound_table[audio_channel[0].current_sample][audio_channel[0].vol];
  104.     if (!(adk & 0x22))
  105.     data += sound_table[audio_channel[1].current_sample][audio_channel[1].vol];
  106.     if (!(adk & 0x44))
  107.     data += sound_table[audio_channel[2].current_sample][audio_channel[2].vol];
  108.     if (!(adk & 0x88))
  109.     data += sound_table[audio_channel[3].current_sample][audio_channel[3].vol];
  110.  
  111.     PUT_SOUND_BYTE (data);
  112.     check_sound_buffers ();
  113. #endif
  114. }
  115.  
  116. static uae_u8 int2ulaw(int ch)
  117. {
  118.     int mask;
  119.  
  120.     if (ch < 0) {
  121.       ch = -ch;
  122.       mask = 0x7f;
  123.     }
  124.     else {
  125.       mask = 0xff;
  126.     }
  127.  
  128.     if (ch < 32) {
  129.     ch = 0xF0 | ( 15 - (ch/2) );
  130.     } else if (ch < 96) {
  131.         ch = 0xE0 | ( 15 - (ch-32)/4 );
  132.     } else if (ch < 224) {
  133.     ch = 0xD0 | ( 15 - (ch-96)/8 );
  134.     } else if (ch < 480) {
  135.     ch = 0xC0 | ( 15 - (ch-224)/16 );
  136.     } else if (ch < 992 ) {
  137.     ch = 0xB0 | ( 15 - (ch-480)/32 );
  138.     } else if (ch < 2016) {
  139.     ch = 0xA0 | ( 15 - (ch-992)/64 );
  140.     } else if (ch < 4064) {
  141.     ch = 0x90 | ( 15 - (ch-2016)/128 );
  142.     } else if (ch < 8160) {
  143.     ch = 0x80 | ( 15 - (ch-4064)/256 );
  144.     } else {
  145.     ch = 0x80;
  146.     }
  147.     return (uae_u8)(mask & ch);
  148. }
  149.  
  150. void sample_ulaw_handler(void)
  151. {
  152. #ifndef DONT_WANT_SOUND
  153.     int nr;
  154.     uae_u32 data = 0;
  155.     char *bp = (char *)sndbufpt;
  156.  
  157.     eventtab[ev_sample].evtime += cycles - eventtab[ev_sample].oldcycles;
  158.     eventtab[ev_sample].oldcycles = cycles;
  159.  
  160.     for (nr = 0; nr < 4; nr++) {
  161.     if (!(adkcon & (0x11 << nr)))
  162.         data += sound_table[audio_channel[nr].current_sample][audio_channel[nr].vol];
  163.     }
  164.     PUT_SOUND_BYTE (int2ulaw (data));
  165.     check_sound_buffers ();
  166. #endif
  167. }
  168.  
  169. #ifndef DONT_WANT_SOUND
  170. static void audio_handler(int nr) 
  171. {
  172.     struct audio_channel_data *cdp = audio_channel + nr;
  173.  
  174.     switch (cdp->state) {
  175.      case 0:
  176.     fprintf(stderr, "Bug in sound code\n");
  177.     break;
  178.  
  179.      case 1:
  180.     /* We come here at the first hsync after DMA was turned on. */
  181.     eventtab[ev_aud0 + nr].evtime += maxhpos;
  182.     eventtab[ev_aud0 + nr].oldcycles += maxhpos;
  183.     
  184.     cdp->state = 5;
  185.     INTREQ(0x8000 | (0x80 << nr));
  186.     if (cdp->wlen != 1)
  187.         cdp->wlen--;
  188.     cdp->nextdat = chipmem_bank.wget(cdp->pt);
  189.  
  190.     cdp->pt += 2;
  191.     break;
  192.  
  193.      case 5:
  194.     /* We come here at the second hsync after DMA was turned on. */
  195.     if (currprefs.produce_sound == 0)
  196.         cdp->per = 65535;
  197.  
  198.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  199.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  200.     cdp->dat = cdp->nextdat;
  201.     cdp->current_sample = (uae_u8)(cdp->dat >> 8);
  202.  
  203.     cdp->state = 2;
  204.     {
  205.         int audav = adkcon & (1 << nr);
  206.         int audap = adkcon & (16 << nr);
  207.         int napnav = (!audav && !audap) || audav;
  208.         if (napnav)
  209.         cdp->data_written = 2;
  210.     }
  211.     break;
  212.     
  213.      case 2:
  214.     /* We come here when a 2->3 transition occurs */
  215.     if (currprefs.produce_sound == 0)
  216.         cdp->per = 65535;
  217.  
  218.     cdp->current_sample = (uae_u8)(cdp->dat & 0xFF);
  219.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  220.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  221.  
  222.     cdp->state = 3;
  223.  
  224.     /* Period attachment? */
  225.     if (adkcon & (0x10 << nr)) {
  226.         if (cdp->intreq2 && cdp->dmaen)
  227.         INTREQ(0x8000 | (0x80 << nr));
  228.         cdp->intreq2 = 0;
  229.  
  230.         cdp->dat = cdp->nextdat;
  231.         if (cdp->dmaen)
  232.         cdp->data_written = 2;
  233.         if (nr < 3) {
  234.         if (cdp->dat == 0)
  235.             (cdp+1)->per = 65535;
  236.  
  237.         else if (cdp->dat < maxhpos/2 && currprefs.produce_sound < 3)
  238.             (cdp+1)->per = maxhpos/2;
  239.         else
  240.             (cdp+1)->per = cdp->dat;
  241.         }
  242.     }
  243.     break;
  244.     
  245.      case 3:
  246.     /* We come here when a 3->2 transition occurs */
  247.     if (currprefs.produce_sound == 0)
  248.         cdp->per = 65535;
  249.  
  250.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  251.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  252.     
  253.     if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
  254.         cdp->state = 0;
  255.         cdp->current_sample = 0;
  256.         eventtab[ev_aud0 + nr].active = 0;
  257.         break;
  258.     } else {
  259.         int audav = adkcon & (1 << nr);
  260.         int audap = adkcon & (16 << nr);
  261.         int napnav = (!audav && !audap) || audav;
  262.         cdp->state = 2;
  263.         
  264.         if ((cdp->intreq2 && cdp->dmaen && napnav)
  265.         || (napnav && !cdp->dmaen))
  266.         INTREQ(0x8000 | (0x80 << nr));
  267.         cdp->intreq2 = 0;
  268.         
  269.         cdp->dat = cdp->nextdat;
  270.         cdp->current_sample = (uae_u8)(cdp->dat >> 8);
  271.  
  272.         if (cdp->dmaen && napnav)
  273.         cdp->data_written = 2;
  274.         
  275.         /* Volume attachment? */
  276.         if (audav) {
  277.         if (nr < 3)
  278.             (cdp+1)->vol = cdp->dat;
  279.         }
  280.     }
  281.     break;
  282.         
  283.      default:
  284.     cdp->state = 0;
  285.     eventtab[ev_aud0 + nr].active = 0;
  286.     break;
  287.     }
  288. }
  289.  
  290. void aud0_handler(void)
  291. {
  292.     audio_handler(0);
  293. }
  294. void aud1_handler(void)
  295. {
  296.     audio_handler(1);
  297. }
  298. void aud2_handler(void)
  299. {
  300.     audio_handler(2);
  301. }
  302. void aud3_handler(void)
  303. {
  304.     audio_handler(3);
  305. }
  306. #endif
  307.